package com.starsky.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @desc: 转换工具类
 * @author: wangsh
 */
public class ConvertUtils {
    private static Logger log = LoggerFactory.getLogger(ConvertUtils.class);

    public static <T> T sourceToTarget(Object source, Class<T> target) {
        if (source == null) {
            return null;
        }
        T targetObject = null;
        try {
            targetObject = target.newInstance();
            BeanUtils.copyProperties(source, targetObject);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("convert error ", e);
        }

        return targetObject;
    }

    public static <T> List<T> sourceToTarget(Collection<?> sourceList, Class<T> target) {
        if (sourceList == null) {
            return null;
        }

        List targetList = new ArrayList<>(sourceList.size());
        try {
            for (Object source : sourceList) {
                T targetObject = target.newInstance();
                BeanUtils.copyProperties(source, targetObject);
                targetList.add(targetObject);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("convert error ", e);
        }

        return targetList;
    }


    /**
     * 将Object对象里面的属性和值转化成Map对象
     *
     * @param obj
     * @return
     */
    public static Map<String, Object> objectToMap(Object obj) {
        Map<String, Object> stringObjectMap = JSON.parseObject(JSON.toJSONString(obj), new TypeReference<Map<String, Object>>() {
        });
        return stringObjectMap;
    }


    /**
     * 将java对象转为二进制数据,对象类一定要实现序列号接口Serializable，否则提示序列化异常
     *
     * @param param
     * @return
     */
    public static byte[] objectToByte(Object param) {
        ByteArrayOutputStream byt = null;
        ObjectOutputStream obj = null;
        try {
            byt = new ByteArrayOutputStream();
            obj = new ObjectOutputStream(byt);
            obj.writeObject(param);
            byte[] bytes = byt.toByteArray();
            log.info("将对象转为二进制数据: " + new String(bytes));
            return bytes;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("将对象转为二进制数据异常：" + e.getMessage());
        } finally {
            IOUtils.closeQuietly(byt);
            IOUtils.closeQuietly(obj);
        }
        return null;
    }

    /**
     * 把二进制数组的数据转回java对象
     *
     * @param param
     * @return
     */
    public static Object byteToObject(byte[] param) {
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        try {
            //读取二进制数据并转换成对象
            bis = new ByteArrayInputStream(param);
            ois = new ObjectInputStream(bis);
            Object obj = ois.readObject();
            log.info("转换结果：" + obj.toString());
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("二进制数据转回对象失败, {}", e);
        } finally {
            IOUtils.closeQuietly(bis);
            IOUtils.closeQuietly(ois);
        }
        return null;
    }

    /**
     * 将字符串通过指定位数插入间隔字符，生成一个新的字符串
     *
     * @param str：字符串
     * @param digit：间隔位数，即几位插入一个字符
     * @param symbol:              插入符号
     */
    public static String insertStr(String str, int digit, String symbol) {
//        str = str.toUpperCase();
        String regex = "(.{" + digit + "})";
        String result = str.replaceAll(regex, "$1" + symbol);
        result = result.substring(0, result.lastIndexOf(symbol));
        return result;
    }

}
